/**
 * create by zhangpu date:2015年3月12日
 */
package com.acooly.module.openapi.client.provider.weixin.marshall;

import java.lang.reflect.Field;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.http.entity.ContentType;
import org.springframework.stereotype.Service;

import com.acooly.core.utils.Reflections;
import com.acooly.core.utils.Strings;
import com.acooly.core.utils.net.HttpResult;
import com.acooly.core.utils.net.Https;
import com.acooly.module.openapi.client.api.exception.ApiClientException;
import com.acooly.module.openapi.client.api.marshal.ApiUnmarshal;
import com.acooly.module.openapi.client.api.message.MessageFactory;
import com.acooly.module.openapi.client.provider.weixin.domain.WeixinNotify;
import com.acooly.module.openapi.client.provider.weixin.support.WeixinAlias;
import com.acooly.module.openapi.client.provider.weixin.utils.XmlUtils;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import com.google.common.collect.Maps;

import lombok.extern.slf4j.Slf4j;

/**
 * @author zhangpu
 */
@Service
@Slf4j
public class WeixinNotifyUnmarshall
        implements ApiUnmarshal<WeixinNotify, Map<String, String>> {

    @Resource(name = "weixinMessageFactory")
    private MessageFactory messageFactory;
    @Resource(name = "wxPayService")
    private WxPayService client;
    
    @Override
    public WeixinNotify unmarshal(Map<String, String> notifyMessage, String serviceName) {
        try {
            log.info("异步通知报文{}", notifyMessage);   
            verifySign(notifyMessage);
            return doUnmarshall(notifyMessage, serviceName);
        } catch (Exception e) {
        	e.printStackTrace();
            throw new ApiClientException("异步通知 解析失败:" + e.getMessage());
        }
    }

    protected WeixinNotify doUnmarshall(Map<String, String> message, String serviceName) {
    	WeixinNotify notify = 
                (WeixinNotify) messageFactory.getNotify(serviceName);
        Set<Field> fields = Reflections.getFields(notify.getClass());
        String key = null;
        for (Field field : fields) {
            WeixinAlias alias = field.getAnnotation(WeixinAlias.class);
            if (alias != null && Strings.isNotBlank(alias.value())) {
                key = alias.value();
            } else {
                key = field.getName();
            }
            Reflections.invokeSetter(notify, field.getName(), message.get(key));
        }
        return notify;
    }

    public void verifySign(Map<String, String> params) {
        try {
        	client.parseOrderNotifyResult(XmlUtils.toXml(params));
            log.info("验签成功");
        } catch (WxPayException e){
        	throw new ApiClientException("通知验签失败:"+e.getErrCodeDes());
        } catch (Exception e) {
            log.info("验签失败，响应报文：{}", params);
            throw new ApiClientException("通知验签失败");
        }
    }

    public void setMessageFactory(MessageFactory messageFactory) {
        this.messageFactory = messageFactory;
    }
    public void setClient(WxPayService client) {
        this.client = client;
    }
}
